<template>
  <view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear">
    <uni-transition v-if="maskShow" class="uni-mask--hook" :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans" @click="onTap" />
    <uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
      <view
        :style="{
          borderRadius: radiusStyle.borderRadius
        }"
        class="uni-popup__wrapper-box"
        @click.stop="clear">
        <slot />
      </view>
    </uni-transition>
  </view>
</template>

<script>
  import uniTransition from '../uni-transition/uni-transition.vue'
  import popup from './popup.js'
  /**
   * PopUp 弹出层
   * @description 弹出层组件，为了解决遮罩弹层的问题
   * @tutorial https://ext.dcloud.net.cn/plugin?id=329
   * @property {String} type = [top|center|bottom] 弹出方式
   * 	@value top 顶部弹出
   * 	@value center 中间弹出
   * 	@value bottom 底部弹出
   * 	@value message 消息提示
   * 	@value dialog 对话框
   * 	@value share 底部分享示例
   * @property {String} radius wrapper 圆角
   * @property {Boolean} animation = [ture|false] 是否开启动画
   * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
   * @event {Function} change 打开关闭弹窗触发，e={show: false}
   */

  export default {
    name: 'UniPopup',
    components: {
      uniTransition
    },
    mixins: [popup],
    provide() {
      return {
        popup: this
      }
    },
    props: {
      // 开启动画
      animation: {
        type: Boolean,
        default: true
      },
      // 弹出层类型，可选值，top: 顶部弹出层；bottom：底部弹出层；center：全屏弹出层
      // message: 消息提示 ; dialog : 对话框
      type: {
        type: String,
        default: 'center'
      },
      // maskClick
      maskClick: {
        type: Boolean,
        default: true
      },
      radius: {
        type: String,
        default: '0 0 0 0'
      }
    },
    data() {
      return {
        duration: 300,
        ani: [],
        showPopup: false,
        showTrans: false,
        maskClass: {
          'position': 'fixed',
          'bottom': 0,
          'top': 0,
          'left': 0,
          'right': 0,
          'backgroundColor': 'rgba(0, 0, 0, 0.4)'
        },
        transClass: {
          'position': 'fixed',
          'left': 0,
          'right': 0,
        },
        maskShow: true,
        mkclick: true,
        popupstyle: 'top'
      }
    },
    computed: {
      radiusStyle() {
        if (this.$isEmpty(this.radius)) {
          return {}
        }
        const res = []
        const arr = this.radius.split(' ')
        arr.forEach(item => {
          let num = 0
          if (item.endsWith('rpx')) {
            num = Number(item.replace('rpx', ''))
            num = isNaN(num) ? 0 : uni.upx2px(num)
          } else if (item.endsWith('px')) {
            num = Number(item.replace('px', ''))
            num = isNaN(num) ? 0 : num
          }
          res.push(num + 'px')
        })
        return {
          borderRadius: res.join(' ')
        }
      }
    },
    watch: {
      /**
       * 监听type类型
       */
      type: {
        handler: function(newVal) {
          this[this.config[newVal]]()
        },
        immediate: true
      },
      /**
       * 监听遮罩是否可点击
       * @param {Object} val
       */
      maskClick(val) {
        this.mkclick = val
      }
    },
    created() {
      this.mkclick = this.maskClick
      if (this.animation) {
        this.duration = 300
      } else {
        this.duration = 0
      }
    },
    methods: {
      clear(e) {
        // TODO nvue 取消冒泡
        e.stopPropagation()
      },
      open() {
        this.showPopup = true
        this.$nextTick(() => {
          new Promise(resolve => {
            clearTimeout(this.timer)
            this.timer = setTimeout(() => {
              this.showTrans = true
              // fixed by mehaotian 兼容 app 端
              this.$nextTick(() => {
                resolve();
              })
            }, 50);
          }).then(res => {
            // 自定义打开事件
            clearTimeout(this.msgtimer)
            this.msgtimer = setTimeout(() => {
              this.customOpen && this.customOpen()
            }, 100)
            this.$emit('change', {
              show: true,
              type: this.type
            })
          })
        })
      },
      close(type) {
        this.showTrans = false
        this.$nextTick(() => {
          this.$emit('change', {
            show: false,
            type: this.type
          })
          clearTimeout(this.timer)
          // 自定义关闭事件
          this.customOpen && this.customClose()
          this.timer = setTimeout(() => {
            this.showPopup = false
          }, 300)
        })
      },
      onTap() {
        this.$emit('mask-close')
        this.mkclick = this.maskClick
        if (!this.mkclick) return
        this.close()
      },
      /**
       * 顶部弹出样式处理
       */
      top() {
        this.popupstyle = 'top'
        this.ani = ['slide-top']
        this.transClass = {
          'position': 'fixed',
          'left': 0,
          'right': 0,
        }
      },
      /**
       * 底部弹出样式处理
       */
      bottom() {
        this.popupstyle = 'bottom'
        this.ani = ['slide-bottom']
        this.transClass = {
          'position': 'fixed',
          'left': 0,
          'right': 0,
          'bottom': 0
        }
      },
      /**
       * 中间弹出样式处理
       */
      center() {
        this.popupstyle = 'center'
        this.ani = ['zoom-out', 'fade']
        this.transClass = {
          'position': 'fixed',
          /* #ifndef APP-NVUE */
          'display': 'flex',
          'flexDirection': 'column',
          /* #endif */
          'bottom': 0,
          'left': 0,
          'right': 0,
          'top': 0,
          'justifyContent': 'center',
          'alignItems': 'center'
        }
      }
    }
  }
</script>
<style scoped>
	.uni-popup {
		position: fixed;
		z-index: 500;
	}

	.uni-popup__mask {
		position: absolute;
		top: 0;
		bottom: 0;
		left: 0;
		right: 0;
		background-color: rgba(0, 0, 0, 0.4);
		opacity: 0;
	}

	.mask-ani {
		transition-property: opacity;
		transition-duration: 0.2s;
	}

	.uni-top-mask {
		opacity: 1;
	}

	.uni-bottom-mask {
		opacity: 1;
	}

	.uni-center-mask {
		opacity: 1;
	}

	.uni-popup__wrapper {
		/* #ifndef APP-NVUE */
		display: block;
		/* #endif */
		position: absolute;
	}

	.top {
		/* #ifdef H5 */
		top: var(--window-top);
		/* #endif */
		/* #ifndef H5 */
		top: 0;
		/* #endif */
	}

	.bottom {
		bottom: 0;
	}

	.uni-popup__wrapper-box {
		/* #ifndef APP-NVUE */
		display: block;
		/* #endif */
		position: relative;
	}
	
	.bottom .uni-popup__wrapper-box {
		/* iphonex 等安全区设置，底部安全区适配 */
		/* #ifndef APP-NVUE */
		padding: 0;
		padding-bottom: constant(safe-area-inset-bottom);
		padding-bottom: env(safe-area-inset-bottom);
		background-color: white;
		/* #endif */
	}

	.content-ani {
		/* transition: transform 0.3s; */
		transition-property: transform, opacity;
		transition-duration: 0.2s;
	}


	.uni-top-content {
		transform: translateY(0);
	}

	.uni-bottom-content {
		transform: translateY(0);
	}

	.uni-center-content {
		transform: scale(1);
		opacity: 1;
	}
</style>